home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / plotting / imagetoo / imagetl1.lha / Imagetool / src+obj / plot3d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-11  |  8.0 KB  |  325 lines

  1. /* cat > headers/plot3d.h << "EOF" */
  2. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  3. /* plot3d.h: header for plot3d.c file            */
  4. /*         3-D plotting in the imagetool. We use the    */
  5. /*         floating horizon algorithm to remove hiden    */
  6. /*         lines. Arbitrary 3-D rotation is possible    */
  7. /*         by setting up different transformation    */
  8. /*         matrix. Currently, the rotation is about    */
  9. /*         y-axis first and then x-axis, z-axis. The    */
  10. /*         constant PRECISION in const.h is to    */
  11. /*         define the accuracy of line intersections.    */
  12. /*         The bigger the PRECISION, the slower the    */
  13. /*         algorithm. For window of N pixels, it    */
  14. /*         makes no sence to assign PRECISION larger    */
  15. /*         than N. For laser printers, that is a    */
  16. /*         different story.                 */
  17. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  18. /* SCCS information: %W%    %G% - NCSA */
  19.  
  20. #define    plot3d_h    1
  21.  
  22. #include "all.h"
  23. #include "newext.h"
  24.  
  25.     static Point v[8];
  26.  
  27. /* EOF */
  28. /* cat > src+obj/plot3d/plot3d.c << "EOF" */
  29. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  30. /* plot3d: main 3-D plotting routine            */
  31. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  32. /* SCCS information: %W%    %G% - NCSA */
  33.  
  34. /* #include "plot3d.h" */
  35.  
  36. void 
  37. plot3d (datx, daty, datap)
  38.     int             datx, daty;
  39.     Point          *datap;
  40. {
  41.     register        i, j;
  42.     register Point *dp;
  43.     Point           pp, pv, **data;
  44.     float           minx, maxx, miny, maxy, minz, maxz;
  45.     float           factor, tmp;
  46.     int             front;
  47.  
  48.         /* Dynamically allocate spaces for the data array */
  49.     data = (Point **) calloc (daty, sizeof (Point *));
  50.     if (data == NULL)
  51.     {
  52.         msg_write ("Error: Not enough memory to hold plot data matrix.");
  53.         return;
  54.     }
  55.     data[0] = datap;
  56.     for (i = 1; i < daty; i++)
  57.     {
  58.         data[i] = data[i - 1] + datx;
  59.     }
  60.  
  61.     minx = data[0][0].x;
  62.     maxx = data[0][datx - 1].x;
  63.     miny = LARGE;
  64.     maxy = -LARGE;
  65.     factor = (maxx - minx) * 0.00347826;
  66.     for (j = 0; j < daty; j++)
  67.     {
  68.         for (i = 0; i < datx; i++)
  69.         {        /* change rotation system */
  70.             dp = &data[j][i];
  71.             tmp = dp->y;
  72.             dp->y = -(dp->z) * factor;
  73.             dp->z = -tmp;
  74.  
  75.             miny = MIN (miny, dp->y);
  76.             maxy = MAX (maxy, dp->y);
  77.         }
  78.     }
  79.     maxz = data[0][0].z;
  80.     minz = data[daty - 1][0].z;
  81.  
  82.     if (draw_init () != 0)
  83.         return;
  84.     front = plot3d_init (minx, maxx, miny, maxy, minz, maxz);
  85.     plot3d_cube (front, 0);    /* plot front lines of the cube */
  86.  
  87.     if (front >= 4)
  88.     {        /* plot from first row to last */
  89.         xform (&pp, &data[0][0]);    /* 4-7 are the front vertices */
  90.         gfx_move (pp.x, pp.y);
  91.         daty--;
  92.         for (i = 0; i < daty; i++)
  93.         {
  94.             for (j = 0; j < datx; j++)
  95.             {                    /* go this way */
  96.                 xform (&pp, &data[i][j]);    /* __________| */
  97.                 gfx_vector (pp.x, pp.y, 1);    /* |           */
  98.             }
  99.             xform (&pp, &data[i + 1][datx - 1]);
  100.             gfx_vector (pp.x, pp.y, 1);
  101.  
  102.             xform (&pp, &data[i][0]);
  103.             gfx_move (pp.x, pp.y);
  104.         }
  105.  
  106.         for (j = 0; j < datx; j++)
  107.         {        /* the last row */
  108.             xform (&pp, &data[daty][j]);
  109.             gfx_vector (pp.x, pp.y, 1);
  110.         }
  111.         daty++;
  112.     }
  113.     else
  114.     {        /* plot in the other way round */
  115.         xform (&pp, &data[daty - 1][datx - 1]);
  116.         gfx_move (pp.x, pp.y);
  117.         for (i = daty - 1; i > 0; i--)
  118.         {
  119.             for (j = datx - 1; j >= 0; j--)
  120.             {
  121.                 xform (&pp, &data[i][j]);
  122.                 gfx_vector (pp.x, pp.y, 1);
  123.             }
  124.             xform (&pp, &data[i - 1][0]);
  125.             gfx_vector (pp.x, pp.y, 1);
  126.  
  127.             xform (&pp, &data[i][datx - 1]);
  128.             gfx_move (pp.x, pp.y);
  129.         }
  130.  
  131.         for (j = datx - 1; j >= 0; j--)
  132.         {        /* the last row */
  133.             xform (&pp, &data[0][j]);
  134.             gfx_vector (pp.x, pp.y, 1);
  135.         }
  136.     }
  137.     plot3d_cube (front, 1);    /* hiden lines of the cube */
  138.  
  139.     draw_done ();
  140.     free (data);
  141. }
  142. /* EOF */
  143. /* cat > src+obj/plot3d/plot3d_cube.c << "EOF" */
  144. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  145. /* plot3d_cube: plot 3-D cube                */
  146. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  147. /* SCCS information: %W%    %G% - NCSA */
  148.  
  149. /* #include "plot3d.h" */
  150. void 
  151. plot3d_cube (front, flag)
  152.     int             front, flag;
  153. {
  154.     Point           v0, v1, v2, v3, v4, v5, v6, v7;
  155.  
  156.     v0 = v[0 ^ front];
  157.     v1 = v[1 ^ front];    /* remember hypercube ? */
  158.     v2 = v[2 ^ front];
  159.     v3 = v[3 ^ front];    /* play tricks on binary numbers */
  160.     v4 = v[4 ^ front];
  161.     v5 = v[5 ^ front];
  162.     v6 = v[6 ^ front];
  163.     v7 = v[7 ^ front];
  164.  
  165.     if (!flag)
  166.     {        /* front lines */
  167.         gfx_line (v0.x, v0.y, v1.x, v1.y, 0);
  168.         gfx_line (v0.x, v0.y, v2.x, v2.y, 0);
  169.         gfx_line (v0.x, v0.y, v4.x, v4.y, 0);
  170.  
  171.         gfx_line (v3.x, v3.y, v1.x, v1.y, 0);
  172.         gfx_line (v3.x, v3.y, v2.x, v2.y, 0);
  173.  
  174.         gfx_line (v5.x, v5.y, v1.x, v1.y, 0);
  175.         gfx_line (v5.x, v5.y, v4.x, v4.y, 0);
  176.  
  177.         gfx_line (v6.x, v6.y, v2.x, v2.y, 0);
  178.         gfx_line (v6.x, v6.y, v4.x, v4.y, 0);
  179.     }
  180.     else
  181.     {        /* hiden lines */
  182.         gfx_line (v3.x, v3.y, v7.x, v7.y, 1);
  183.         gfx_line (v5.x, v5.y, v7.x, v7.y, 1);
  184.         gfx_line (v6.x, v6.y, v7.x, v7.y, 1);
  185.     }
  186. }
  187. /* EOF */
  188. /* cat > src+obj/plot3d/plot3d_init.c << "EOF" */
  189. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  190. /* plot3d_init: initialize 3-D plotting            */
  191. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  192. /* SCCS information: %W%    %G% - NCSA */
  193.  
  194. /* #include "plot3d.h" */
  195.  
  196. plot3d_init (minx, maxx, miny, maxy, minz, maxz)
  197.     float           minx, maxx, miny, maxy, minz, maxz;
  198. {
  199.     float           h_minx, h_maxx, h_miny, h_maxy;    /* calculation space */
  200.     float           w_minx, w_maxx, w_miny, w_maxy;    /* current window space */
  201.     float           minimum_z, tmp;    /* for drawing cube */
  202.     Point           pp, pv[8];    /* cube vertices */
  203.     int             i, front_vertex;    /* of the cube */
  204.  
  205.     setvrp ((maxx - minx) / 2.0 + minx,    /* view reference point */
  206.         (maxy - miny) / 2.0 + miny,
  207.         (maxz - minz) / 2.0 + minz);
  208.     setxform ();        /* transformation matrix */
  209.     gfx_init ();        /* setup scale to widow size */
  210.  
  211.     pv[0].x = minx;
  212.     pv[0].y = miny;
  213.     pv[0].z = minz;        /* the cube */
  214.     pv[1].x = maxx;
  215.     pv[1].y = miny;
  216.     pv[1].z = minz;
  217.     pv[2].x = minx;
  218.     pv[2].y = maxy;
  219.     pv[2].z = minz;
  220.     pv[3].x = maxx;
  221.     pv[3].y = maxy;
  222.     pv[3].z = minz;
  223.     pv[4].x = minx;
  224.     pv[4].y = miny;
  225.     pv[4].z = maxz;
  226.     pv[5].x = maxx;
  227.     pv[5].y = miny;
  228.     pv[5].z = maxz;
  229.     pv[6].x = minx;
  230.     pv[6].y = maxy;
  231.     pv[6].z = maxz;
  232.     pv[7].x = maxx;
  233.     pv[7].y = maxy;
  234.     pv[7].z = maxz;
  235.  
  236.     for (i = 0; i < 8; i++)
  237.     {
  238.         xform (&v[i], &pv[i]);    /* cube in calculation space */
  239.         pp = v[i];
  240.         zform (&pp);    /* in real space after rotation */
  241.  
  242.         if (i == 0)
  243.         {        /* find out boundary sizes */
  244.             h_minx = h_maxx = v[i].x;    /* for both spaces and the */
  245.             h_miny = h_maxy = v[i].y;    /* front vertex number */
  246.             minimum_z = v[i].z;
  247.             front_vertex = 0;
  248.  
  249.             w_minx = w_maxx = pp.x;
  250.             w_miny = w_maxy = pp.y;
  251.         }
  252.         else
  253.         {
  254.             tmp = v[i].x;
  255.             if (tmp < h_minx)
  256.                 h_minx = tmp;
  257.             else if (tmp > h_maxx)
  258.                 h_maxx = tmp;
  259.  
  260.             tmp = v[i].y;
  261.             if (tmp < h_miny)
  262.                 h_miny = tmp;
  263.             else if (tmp > h_maxy)
  264.                 h_maxy = tmp;
  265.  
  266.             tmp = v[i].z;
  267.             if (tmp < minimum_z)
  268.             {
  269.                 minimum_z = tmp;
  270.                 front_vertex = i;
  271.             }
  272.  
  273.             tmp = pp.x;
  274.             if (tmp < w_minx)
  275.                 w_minx = tmp;
  276.             else if (tmp > w_maxx)
  277.                 w_maxx = tmp;
  278.  
  279.             tmp = pp.y;
  280.             if (tmp < w_miny)
  281.                 w_miny = tmp;
  282.             else if (tmp > w_maxy)
  283.                 w_maxy = tmp;
  284.         }
  285.     }
  286.  
  287.     hid_scale (h_minx, h_maxx, h_miny, h_maxy);    /* scale calculation space */
  288.     win_scale (w_minx, w_maxx, w_miny, w_maxy);    /* scale curr window space */
  289.     return (front_vertex);
  290. }
  291. /* EOF */
  292. /* cat > src+obj/plot3d/plot_threed.c << "EOF" */
  293. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  294. /* plot_threed: 3-D plotting routine            */
  295. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  296. /* SCCS information: %W%    %G% - NCSA */
  297.  
  298. /* #include "plot3d.h" */
  299.  
  300. void 
  301. plot_threed ()
  302. {
  303.     Point          *matrix;    /* hold data to be plotted */
  304.     int             xdim = curr_image.xdim;    /* box dimentions */
  305.     int             ydim = curr_image.ydim;
  306.     int             xpos = curr_image.startx;
  307.     int             ypos = curr_image.starty;
  308.     int             tmp;
  309.  
  310.     clear_plot ();
  311.     tmp = (xdim + 1) >> 1;    /* average data points */
  312.         /* to speed up plotting */
  313.     if ((matrix = (Point *) malloc (tmp * ydim * sizeof (Point))) == NULL)
  314.     {
  315.         msg_write ("Error: Not enough memory to hold plot data matrix.");
  316.         return;
  317.     }
  318.     if (get_matrix (matrix, xdim, ydim, xpos, ypos) != 0)
  319.         return;
  320.  
  321.     plot3d (tmp, ydim, matrix);    /* do the real work */
  322.     free (matrix);
  323. }
  324. /* EOF */
  325.